#include "QtGuiEx/ColorPaletteWidget.qth"
#include "QtGuiEx/ColorPaletteWidget.moh"
#include "QtGuiEx/ColorPaletteButton.qth"
#include <QtGui/QGridLayout>
#include <QtGui/QToolButton>
#include <QtGui/QPixMap>
#include <QtGui/QLabel>
#include <QtGui/QColorDialog>
#include <QtGui/QPushButton>

namespace 
{

const QColor COLORS[5][7] = 
{
{ QColor(  64,   0,   0), QColor( 128,  64,   0), QColor( 128, 128,   0), QColor(   0,  64,   0), QColor(   0,   0,  64), QColor(  64,   0,  64), QColor(   0,   0,   0) },
{ QColor( 128,   0,   0), QColor( 192, 128,   0), QColor( 192, 192,   0), QColor(   0, 128,   0), QColor(   0,   0, 128), QColor( 128,   0, 128), QColor(  64,  64,  64) },
{ QColor( 192,   0,   0), QColor( 255, 192,   0), QColor( 255, 255,   0), QColor(   0, 192,   0), QColor(   0,   0, 192), QColor( 192,   0, 192), QColor( 128, 128, 128) },
{ QColor( 255,   0,   0), QColor( 255, 192,  64), QColor( 255, 255,  64), QColor(   0, 255,   0), QColor(   0,   0, 255), QColor( 255,   0, 255), QColor( 192, 192, 192) },
{ QColor( 255, 128, 128), QColor( 255, 192, 192), QColor( 255, 255, 128), QColor( 128, 255, 128), QColor( 128, 128, 255), QColor( 255, 128, 255), QColor( 255, 255, 255) }
};

} // namespace

namespace QtGuiEx
{

ColorPaletteWidget::ColorPaletteWidget( bool displayClearColor, QWidget* pParent)
	: QMenu( pParent)
	, lastCustomColorSet_( -1)
{
	QGridLayout* pLayout = new QGridLayout();
	this->setLayout( pLayout);
	pLayout->setSpacing( 1);

	int curRowNumber = 0;
	if( displayClearColor) this->insertClearColorWidgets( pLayout, curRowNumber);
	this->insertBasicColorWidgets( pLayout, curRowNumber);
	this->insertCustomColorWidgets( pLayout, curRowNumber);
	this->insertOtherColorsButton( pLayout, curRowNumber);
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::insertClearColorWidgets( QGridLayout* pLayout, int& curRowNumber)
{
	QPushButton* pClearColor = new QPushButton();
	pClearColor->setText( tr( "Clear color"));
	pClearColor->setFlat( true);
	pLayout->addWidget( pClearColor, curRowNumber, 0, 1, nCols);
	connect( pClearColor, SIGNAL( clicked()), this, SLOT( handleClearColorSelected()));

	++curRowNumber;
	pLayout->setRowMinimumHeight( curRowNumber, 10);
	++curRowNumber;
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::insertBasicColorWidgets( QGridLayout* pLayout, int& curRowNumber)
{
	QLabel* pBasicColorsLabel = new QLabel;
	pBasicColorsLabel->setText( tr( "Basic colors: "));
	pLayout->addWidget( pBasicColorsLabel, curRowNumber, 0, 1, nCols);
	++curRowNumber;

	for( int rowN = 0; rowN < nPredefRows; ++rowN, ++curRowNumber)
	{
		for( int colN = 0; colN < nCols; ++colN)
		{
			ColorPaletteButton* pButton = new ColorPaletteButton( COLORS[rowN][colN]);
			pLayout->addWidget( pButton, curRowNumber, colN);
			connect( pButton, SIGNAL( colorSelected( const QColor&)), this, SLOT( handleColorSelected( const QColor&)));
		}
	}

	pLayout->setRowMinimumHeight( curRowNumber, 10);
	++curRowNumber;
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::insertCustomColorWidgets( QGridLayout* pLayout, int& curRowNumber)
{
	QLabel* pCustColorsLabel = new QLabel;
	pCustColorsLabel->setText( tr( "Custom colors: "));
	pLayout->addWidget( pCustColorsLabel, curRowNumber, 0, 1, nCols);
	++curRowNumber;

	for( int rowN = 0; rowN < nCustomRows; ++rowN, ++curRowNumber)
	{
		for( int colN = 0; colN < nCols; ++colN)
		{
			ColorPaletteButton* pButton = new ColorPaletteButton( QColor());
			pLayout->addWidget( pButton, curRowNumber, colN);
			connect( pButton, SIGNAL( colorSelected( const QColor&)), this, SLOT( handleColorSelected( const QColor&)));
			customColorButtons_[rowN*nCols + colN] = pButton;
		}
	}

	pLayout->setRowMinimumHeight( curRowNumber, 10);
	++curRowNumber;
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::insertOtherColorsButton( QGridLayout* pLayout, int& curRowNumber)
{
	QPushButton* pCustomColorsButton = new QPushButton;
	pCustomColorsButton->setFlat( true);
	pCustomColorsButton->setText( tr( "&Other colors..."));
	pLayout->addWidget( pCustomColorsButton, curRowNumber, 0, 1, nCols);
	connect( pCustomColorsButton, SIGNAL( clicked( bool)), this, SLOT( otherColorsSelected()));
	++curRowNumber;
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::handleColorSelected( const QColor& selectedColor)
{
	this->close();
	Q_EMIT colorSelected( selectedColor);
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::otherColorsSelected()
{
	QColor selectedColor = QColorDialog::getColor( Qt::white, this);
	if( selectedColor.isValid())
	{
		this->changeCustomColorButton( selectedColor);
		this->handleColorSelected( selectedColor);
	}
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::handleClearColorSelected()
{
	QColor selectedColor;
	this->handleColorSelected( selectedColor);
}

// ---------------------------------------------------------------------------------------------------------------------

ColorPaletteButton* ColorPaletteWidget::getCustomColorButtonForChange()
{
	lastCustomColorSet_ = (++lastCustomColorSet_) % (nCustomRows*nCols);
	return customColorButtons_[ lastCustomColorSet_];
}

// ---------------------------------------------------------------------------------------------------------------------

void ColorPaletteWidget::changeCustomColorButton( const QColor& newColor)
{
	ColorPaletteButton* pButton = this->getCustomColorButton( newColor);
	if( NULL == pButton)
	{
		pButton = this->getCustomColorButtonForChange();
		pButton->setColor( newColor);
	}
}

// ---------------------------------------------------------------------------------------------------------------------

ColorPaletteButton* ColorPaletteWidget::getCustomColorButton( const QColor& newColor)
{
	for( int i = 0;i < nCustomRows*nCols; ++i)
	{
		if( newColor == customColorButtons_[i]->color())
		{
			return customColorButtons_[i];
		}
	}
	return NULL;
}

} // namespace QtGuiEx
